package com.moxiao.yfjh.module.order.tradeRefund.blindTradeOrder;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.gson.Gson;
import com.moxiao.yfjh.framework.common.pojo.PageResult;
import com.moxiao.yfjh.framework.pay.core.client.dto.order.PayOrderRespDTO;
import com.moxiao.yfjh.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import com.moxiao.yfjh.module.activity.controller.admin.activityEnroll.vo.ActivityEnrollUpdateReqVO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityEnroll.ActivityEnrollDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityInfo.ActivityInfoDO;
import com.moxiao.yfjh.module.activity.service.activityEnroll.ActivityEnrollService;
import com.moxiao.yfjh.module.activity.service.activityInfo.ActivityInfoService;
import com.moxiao.yfjh.module.blind.controller.admin.member.vo.BlindMemberUserUpdateReqVO;
import com.moxiao.yfjh.module.blind.dal.dataobject.basicSetting.BlindBasicSettingDO;
import com.moxiao.yfjh.module.blind.dal.dataobject.mechanism.MemberMechanismDO;
import com.moxiao.yfjh.module.blind.dal.dataobject.member.BlindMemberUserDO;
import com.moxiao.yfjh.module.blind.dal.dataobject.recommendSetting.RecommendSettingDO;
import com.moxiao.yfjh.module.blind.service.basicSetting.BlindBasicSettingService;
import com.moxiao.yfjh.module.blind.service.mechanism.MemberMechanismService;
import com.moxiao.yfjh.module.blind.service.member.BlindMemberUserService;
import com.moxiao.yfjh.module.blind.service.recommendSetting.RecommendSettingService;
import com.moxiao.yfjh.module.maker.controller.admin.memberStringing.vo.MatchmakerMemberStringingCreateReqVO;
import com.moxiao.yfjh.module.maker.dal.dataobject.memberStringing.MatchmakerMemberStringingDO;
import com.moxiao.yfjh.module.maker.service.memberStringing.MatchmakerMemberStringingService;
import com.moxiao.yfjh.module.order.common.GenNoCommonUtil;
import com.moxiao.yfjh.module.order.common.NoCommonUtil;
import com.moxiao.yfjh.module.order.controller.admin.blindTradeOrder.vo.BlindTradeOrderCreateReqVO;
import com.moxiao.yfjh.module.order.controller.admin.blindTradeOrder.vo.BlindTradeOrderExportReqVO;
import com.moxiao.yfjh.module.order.controller.admin.blindTradeOrder.vo.BlindTradeOrderPageReqVO;
import com.moxiao.yfjh.module.order.controller.admin.blindTradeOrder.vo.BlindTradeOrderUpdateReqVO;
import com.moxiao.yfjh.module.order.controller.admin.brokeragerecord.vo.BlindBrokerageRecordCreateReqVO;
import com.moxiao.yfjh.module.order.controller.admin.brokeragerecord.vo.BlindBrokerageRecordExportReqVO;
import com.moxiao.yfjh.module.order.controller.app.vo.*;
import com.moxiao.yfjh.module.order.convert.blindTradeOrder.BlindTradeOrderConvert;
import com.moxiao.yfjh.module.order.dal.dataobject.blindTradeOrder.BlindTradeOrderDO;
import com.moxiao.yfjh.module.order.dal.dataobject.brokeragerecord.BlindBrokerageRecordDO;
import com.moxiao.yfjh.module.order.dal.mysql.blindTradeOrder.BlindTradeOrderMapper;
import com.moxiao.yfjh.module.order.tradeRefund.brokeragerecord.BlindBrokerageRecordService;
import com.moxiao.yfjh.module.pay.api.order.dto.PayOrderCreateReqDTO;
import com.moxiao.yfjh.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
import com.moxiao.yfjh.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
import com.moxiao.yfjh.module.pay.dal.dataobject.app.PayAppDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.channel.PayChannelDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.order.PayOrderDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.order.PayOrderExtensionDO;
import com.moxiao.yfjh.module.pay.dal.mysql.order.PayOrderExtensionMapper;
import com.moxiao.yfjh.module.pay.dal.mysql.order.PayOrderMapper;
import com.moxiao.yfjh.module.pay.enums.order.PayOrderOpenLeveleEnum;
import com.moxiao.yfjh.module.pay.enums.order.PayOrderStatusEnum;
import com.moxiao.yfjh.module.pay.enums.order.PayOrderTypeEnum;
import com.moxiao.yfjh.module.pay.service.app.PayAppService;
import com.moxiao.yfjh.module.pay.service.channel.PayChannelService;
import com.moxiao.yfjh.module.pay.service.order.PayOrderService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.util.*;

import static com.moxiao.yfjh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.moxiao.yfjh.framework.common.util.json.JsonUtils.toJsonString;
import static com.moxiao.yfjh.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.moxiao.yfjh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.PAY_ORDER_EXISTS;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.PAY_USER_NOT_ORDER_EXISTS;
import static com.moxiao.yfjh.module.order.enums.ErrorCodeConstants.BLIND_TRADE_ORDER_NOT_EXISTS;
import static com.moxiao.yfjh.module.pay.enums.ErrorCodeConstants.PAY_ORDER_EXTENSION_NOT_FOUND;
import static com.moxiao.yfjh.module.pay.enums.ErrorCodeConstants.PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING;

/**
 * 相亲交易订单 Service 实现类
 *
 * @author mx
 */
@Service
@Validated
public class BlindTradeOrderServiceImpl implements BlindTradeOrderService {

    private static final Logger log = LoggerFactory.getLogger(BlindTradeOrderServiceImpl.class);
    @Resource
    private BlindTradeOrderMapper blindTradeOrderMapper;
    @Resource
    private GenNoCommonUtil genNoCommonUtil;
    @Resource
    private MemberMechanismService memberMechanismService;
    @Resource
    private BlindMemberUserService blindMemberUserService;
    @Resource
    private RecommendSettingService recommendSettingService;
    @Resource
    private ActivityInfoService activityInfoService;
    @Resource
    private ActivityEnrollService activityEnrollService;
    @Resource
    private BlindBasicSettingService basicSettingService;
    @Resource
    private BlindBrokerageRecordService brokerageRecordService;
    @Resource
    private MatchmakerMemberStringingService memberStringing;

    @Resource
    private PayOrderService payOrderService;
    @Resource
    private PayAppService payAppService;
    @Resource
    private PayOrderExtensionMapper orderExtensionMapper;
    @Resource
    private PayOrderMapper orderMapper;
    @Resource
    private PayChannelService channelService;

    @Override
    public Long createBlindTradeOrder(BlindTradeOrderCreateReqVO createReqVO) {
        // 插入
        BlindTradeOrderDO blindTradeOrder = BlindTradeOrderConvert.INSTANCE.convert(createReqVO);
        blindTradeOrderMapper.insert(blindTradeOrder);
        // 返回
        return blindTradeOrder.getId();
    }

    @Override
    public void updateBlindTradeOrder(BlindTradeOrderUpdateReqVO updateReqVO) {
        // 校验存在
        validateBlindTradeOrderExists(updateReqVO.getId());
        // 更新
        BlindTradeOrderDO updateObj = BlindTradeOrderConvert.INSTANCE.convert(updateReqVO);
        blindTradeOrderMapper.updateById(updateObj);
    }

    @Override
    public void deleteBlindTradeOrder(Long id) {
        // 校验存在
        validateBlindTradeOrderExists(id);
        // 删除
        blindTradeOrderMapper.deleteById(id);
    }

    private void validateBlindTradeOrderExists(Long id) {
        if (blindTradeOrderMapper.selectById(id) == null) {
            throw exception(BLIND_TRADE_ORDER_NOT_EXISTS);
        }
    }

    @Override
    public BlindTradeOrderDO getBlindTradeOrder(Long id) {
        return blindTradeOrderMapper.selectById(id);
    }

    @Override
    public List<BlindTradeOrderDO> getBlindTradeOrderList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return blindTradeOrderMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<BlindTradeOrderDO> getBlindTradeOrderPage(BlindTradeOrderPageReqVO pageReqVO) {
        return blindTradeOrderMapper.selectPage(pageReqVO);
    }

    @Override
    public List<BlindTradeOrderDO> getBlindTradeOrderList(BlindTradeOrderExportReqVO exportReqVO) {
        return blindTradeOrderMapper.selectList(exportReqVO);
    }

    @Override
    public BlindTradeOrderDO getTradeOrderTodayLast(Date todayStart, Date todayEnd) {
        LambdaQueryWrapper<BlindTradeOrderDO> lqw = Wrappers.lambdaQuery();
        if (Objects.nonNull(todayStart) && Objects.nonNull(todayEnd)) {
            lqw.between(BlindTradeOrderDO::getCreateTime, todayStart, todayEnd);
        }
        lqw.orderByDesc(BlindTradeOrderDO::getCreateTime);
        lqw.last("LIMIT " + 1);
        return this.blindTradeOrderMapper.selectOne(lqw);
    }

    @Override
    public Integer getTradeOrderNo(String orderNo) {
        return blindTradeOrderMapper.getMemberUserNo(orderNo);
    }


    @Override
    public Object createOrder(AppBlindOrderCreateReqVO appBlindOrderCreateReqVO) {
        if (Objects.isNull(appBlindOrderCreateReqVO.getMechanismId())) {
            throw new UnsupportedOperationException("会员机n制id为空");
        }
        MemberMechanismDO memberMechanism = memberMechanismService.getMemberMechanism(appBlindOrderCreateReqVO.getMechanismId());
        if (Objects.isNull(memberMechanism)) {
            throw new UnsupportedOperationException("会员机制不存在");
        }
        BlindMemberUserDO memberUser = blindMemberUserService.getMemberUser(appBlindOrderCreateReqVO.getUserId());
        if (Objects.isNull(memberUser)) {
            throw new UnsupportedOperationException("会员信息不存在");
        }
        // 创建交易订单
        Long blindOrder = createBlindOrder(appBlindOrderCreateReqVO, memberMechanism, memberUser);
        Object jsonObject = null;
        if (appBlindOrderCreateReqVO.getDeviceType() == 1) {
            log.info("开通会员，提交会员支付订单{}", System.currentTimeMillis());
            // 统一支付相关逻辑
            AppBlindOrderCreateRespVO appBlindOrderCreateRespVO = new AppBlindOrderCreateRespVO();
            //1.为支付设置
            appBlindOrderCreateRespVO.setStatus((PayOrderStatusEnum.SUCCESS.getStatus()));
            appBlindOrderCreateRespVO.setMemberOrderId(blindOrder);
            // 2.设置支付金额，将金额转成分
            BigDecimal cents = memberMechanism.getMoney().multiply(new BigDecimal("100"));
            int intValue = cents.intValue();
            appBlindOrderCreateRespVO.setAmount(intValue);
            appBlindOrderCreateRespVO.setMemberUserId(appBlindOrderCreateReqVO.getUserId());
            appBlindOrderCreateRespVO.setType(PayOrderOpenLeveleEnum.Regular_members.getType());
            // 3.统一下单，并返回支付串
            appBlindOrderCreateRespVO.setType(Integer.valueOf(appBlindOrderCreateReqVO.getPayway()));
            PayOrderSubmitRespVO payOrderSubmitRespVO = createPayOrder(appBlindOrderCreateRespVO);
            Gson gson = new Gson();
            if (appBlindOrderCreateRespVO.getType() == 1) {
                jsonObject = gson.fromJson(payOrderSubmitRespVO.getDisplayContent(), Object.class);
            } else {
                jsonObject = payOrderSubmitRespVO.getDisplayContent();
            }
        } else {
            BlindMemberUserUpdateReqVO updateReqVO = new BlindMemberUserUpdateReqVO();
            updateReqVO.setHaveMember((byte) 1);
            updateReqVO.setId(memberUser.getId());
            updateReqVO.setMemberEndTime(memberUser.getMemberEndTime());
            getSelf().updateMemberUser(memberMechanism, updateReqVO);
        }
        // 查询基础设置中的分销设置
        BlindBasicSettingDO basicSetting = basicSettingService.getBasicSetting(1L);
        // 是否超过分销时间
//        boolean t = getDateTime(basicSetting.getEffectiveTime());
        // 如果当前用户的所属分销员已获得分销佣金，则不能重复获得分销金额
        if (StringUtils.isNotEmpty(memberUser.getDistributors())) {
            BlindBrokerageRecordExportReqVO blindBrokerageRecordExportReqVO = new BlindBrokerageRecordExportReqVO();
            blindBrokerageRecordExportReqVO.setUserId(Long.valueOf(memberUser.getDistributors()));
            blindBrokerageRecordExportReqVO.setSourceUserId(memberUser.getId());
            List<BlindBrokerageRecordDO> list = brokerageRecordService.getBrokerageRecordList(blindBrokerageRecordExportReqVO);
            if (list.isEmpty()) {
                // 有分销员才会计算分销金额
                if (StringUtils.isNotBlank(memberUser.getDistributors())) {
                    // 计算上级可得的分销金额
                    BigDecimal amount = memberMechanism.getMoney();
                    // （金额 * 比例）/ 100
                    BigDecimal jisuan = amount.multiply(BigDecimal.valueOf(basicSetting.getCommissionRatio())).divide(BigDecimal.valueOf(100), RoundingMode.HALF_UP);
                    BigDecimal roundedValue = jisuan.setScale(2, RoundingMode.HALF_UP);
                    // 增加佣金记录
                    BlindBrokerageRecordCreateReqVO brokerageRecordCreateReqVO = new BlindBrokerageRecordCreateReqVO();
                    brokerageRecordCreateReqVO.setBizId(NoCommonUtil.getDistribution(memberUser.getId()));
                    brokerageRecordCreateReqVO.setUserId(Long.valueOf(memberUser.getDistributors()));
                    brokerageRecordCreateReqVO.setBizType((byte) 1);
                    brokerageRecordCreateReqVO.setPrice(roundedValue);
                    brokerageRecordCreateReqVO.setTotalPrice(roundedValue);
                    brokerageRecordCreateReqVO.setTitle("会员开通获得佣金");
                    brokerageRecordCreateReqVO.setStatus((byte) 1);
                    brokerageRecordCreateReqVO.setFrozenDays(10);
                    // 会员订单id
                    brokerageRecordCreateReqVO.setOrderId(blindOrder);
                    brokerageRecordCreateReqVO.setSourceUserLevel(Integer.valueOf(memberUser.getUserLevel()));
                    brokerageRecordCreateReqVO.setSourceUserId(memberUser.getId());
                    brokerageRecordCreateReqVO.setTotalPrice(memberMechanism.getMoney());
                    brokerageRecordCreateReqVO.setOrderId(appBlindOrderCreateReqVO.getMechanismId());
                    brokerageRecordCreateReqVO.setDescription("分销佣金：会员：" + memberUser.getNickname() + "，开通会员后，您获得了佣金");
                    brokerageRecordService.createBrokerageRecord(brokerageRecordCreateReqVO);
                }
            }
        }
        return jsonObject;
    }

    /**
     * 分销时间是否已超过
     */
    public boolean getDateTime(Integer hour) {
        boolean t = false;
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        // 获取当前系统时间
        Calendar currentTime = Calendar.getInstance();
        if (calendar.after(currentTime)) {
            t = true;
            System.out.println("超过了当前系统时间");
        } else {
            t = false;
            System.out.println("未超过当前系统时间");
        }
        return t;
    }


    @Override
    public Object createRecommendOrder(AppRecommendOrderReqVO appRecommendOrderReqVO) {
        if (Objects.isNull(appRecommendOrderReqVO.getRecommendId())) {
            throw new UnsupportedOperationException("会员机制id为空");
        }
        RecommendSettingDO recommendSetting = recommendSettingService.getRecommendSetting(appRecommendOrderReqVO.getRecommendId());
        if (Objects.isNull(recommendSetting)) {
            throw new UnsupportedOperationException("超级推荐设置信息不存在");
        }

        BlindMemberUserDO memberUser = blindMemberUserService.getMemberUser(appRecommendOrderReqVO.getUserId());
        if (Objects.isNull(memberUser)) {
            throw new UnsupportedOperationException("会员信息不存在");
        }
        // 创建相亲交易订单
        Long blindOrder = createRecommendOrder(appRecommendOrderReqVO, recommendSetting, memberUser);
        Object jsonObject = new Object();
        if (appRecommendOrderReqVO.getDeviceType() == 1) {
            // 超级推荐统一支付相关
            AppBlindOrderCreateRespVO appBlindOrderCreateRespVO = new AppBlindOrderCreateRespVO();
            appBlindOrderCreateRespVO.setMemberOrderId(blindOrder);
            appBlindOrderCreateRespVO.setMemberUserId(appRecommendOrderReqVO.getUserId());
            // 2.设置支付金额，将金额转成分
            BigDecimal cents = recommendSetting.getMoney().multiply(new BigDecimal("100"));
            int intValue = cents.intValue();
            appBlindOrderCreateRespVO.setAmount(intValue);
            appBlindOrderCreateRespVO.setStatus((PayOrderStatusEnum.WAITING.getStatus()));
            appBlindOrderCreateRespVO.setMemberOrderId(blindOrder);
            appBlindOrderCreateRespVO.setType(PayOrderOpenLeveleEnum.SUPER_RECOMMENDATION.getType());
            // 3.统一下单，并返回支付串
            appBlindOrderCreateRespVO.setType(Integer.valueOf(appRecommendOrderReqVO.getPayway()));
            PayOrderSubmitRespVO payOrderSubmitRespVO = createPayOrder(appBlindOrderCreateRespVO);
            log.info("购买超级推荐，提交超级推荐支付订单");
            Gson gson = new Gson();
            if (appBlindOrderCreateRespVO.getType() == 1) {
                jsonObject = gson.fromJson(payOrderSubmitRespVO.getDisplayContent(), Object.class);
            } else {
                jsonObject = payOrderSubmitRespVO.getDisplayContent();
            }
        } else {
            getSelf().updateRecommendMemberUser(recommendSetting, memberUser);
            AppBlindOrderCreateRespVO appBlindOrderCreateRespVO = new AppBlindOrderCreateRespVO();
            appBlindOrderCreateRespVO.setStatus(1);
            appBlindOrderCreateRespVO.setMemberOrderId(blindOrder);
            appBlindOrderCreateRespVO.setMemberUserId(appRecommendOrderReqVO.getUserId());
            BigDecimal cents = recommendSetting.getMoney().multiply(new BigDecimal("100"));
            int intValue = cents.intValue();
            appBlindOrderCreateRespVO.setAmount(intValue);
            return appBlindOrderCreateRespVO;
        }
        return jsonObject;
    }

    @Override
    public Object createBlindMakerOrder(AppMakerOrderReqVO appdOrderReqVO) {

        BlindMemberUserDO memberUser = blindMemberUserService.getMemberUser(appdOrderReqVO.getUserId());
        if (Objects.isNull(memberUser)) {
            throw new UnsupportedOperationException("会员信息不存在");
        }
        // 创建交易订单
        Long blindOrder = createBlindMakerOrder(appdOrderReqVO, memberUser);
        AppBlindOrderCreateRespVO appBlindOrderCreateRespVO = new AppBlindOrderCreateRespVO();
        appBlindOrderCreateRespVO.setStatus(1);
        appBlindOrderCreateRespVO.setMemberOrderId(blindOrder);
        appBlindOrderCreateRespVO.setMemberUserId(appdOrderReqVO.getUserId());
        appBlindOrderCreateRespVO.setType(PayOrderOpenLeveleEnum.MATCHMAKER_SERVICE.getType());
        BigDecimal cents = appdOrderReqVO.getMoney().multiply(new BigDecimal("100"));
        int intValue = cents.intValue();
        appBlindOrderCreateRespVO.setAmount(intValue);
        Object jsonObject = new Object();
        if (appdOrderReqVO.getDeviceType() == 1) {
            //返回支付
            appBlindOrderCreateRespVO.setType(PayOrderOpenLeveleEnum.MATCHMAKER_SERVICE.getType());
            log.info("红娘服务，提交红娘服务支付订单");
            appBlindOrderCreateRespVO.setType(Integer.valueOf(appdOrderReqVO.getPayway()));
            PayOrderSubmitRespVO payOrderSubmitRespVO = createPayOrder(appBlindOrderCreateRespVO);
            Gson gson = new Gson();

            if (appBlindOrderCreateRespVO.getType() == 1) {
                jsonObject = gson.fromJson(payOrderSubmitRespVO.getDisplayContent(), Object.class);
            } else {
                jsonObject = payOrderSubmitRespVO.getDisplayContent();
            }
            return jsonObject;
        } else {
            MatchmakerMemberStringingDO memberStringingDO = memberStringing.getSelectOne(memberUser.getId());
            if (Objects.nonNull(memberStringingDO)) {
                int num = memberStringingDO.getStringingNum() + 1;
                memberStringing.updateNum(memberStringingDO.getId(), num);
            } else {
                MatchmakerMemberStringingCreateReqVO createReqVO = new MatchmakerMemberStringingCreateReqVO();
                createReqVO.setStringingNum(1);
                createReqVO.setMemberId(memberUser.getId());
                createReqVO.setMemberName(memberUser.getNickname());
                Long id = memberStringing.createMatchmakerMemberStringing(createReqVO);
            }
            return jsonObject;
        }
    }

    @Override
    public AppBlindOrderCreateRespVO createActivityOrder(AppActivityOrderReqVO appActivityOrderReqVO) {
        log.info("开通会员，提交会员支付订单 开始时间" + System.currentTimeMillis());

        if (Objects.isNull(appActivityOrderReqVO.getActivityId())) {
            throw new UnsupportedOperationException("活动id为空");
        }

        ActivityInfoDO info = activityInfoService.getInfo(appActivityOrderReqVO.getActivityId());
        if (Objects.isNull(info)) {
            throw new UnsupportedOperationException("活动信息为空");
        }
        BlindMemberUserDO memberUser = blindMemberUserService.getMemberUser(appActivityOrderReqVO.getUserId());
        if (Objects.isNull(memberUser)) {
            throw new UnsupportedOperationException("会员信息不存在");
        }
        Long blindOrder = createActivityOrder(appActivityOrderReqVO, info, memberUser);
        log.info("开通会员，提交会员支付订单 结束" + System.currentTimeMillis());

        // 最后一个人付款 将活动状态变成未开始
        updateActivityEnroll(info, appActivityOrderReqVO, blindOrder);
        log.info("开通会员，提交会员支付订单 修改活动" + System.currentTimeMillis());

        AppBlindOrderCreateRespVO appBlindOrderCreateRespVO = new AppBlindOrderCreateRespVO();
        appBlindOrderCreateRespVO.setStatus(1);
        return appBlindOrderCreateRespVO;

    }

    /**
     * 修改活动报名信息
     *
     * @param info
     * @param appActivityOrderReqVO
     * @param blindOrder
     */
    private void updateActivityEnroll(ActivityInfoDO info, AppActivityOrderReqVO appActivityOrderReqVO, Long blindOrder) {
        //当前活动 及当前付款人信息
        ActivityEnrollDO activityEnrollDO = activityEnrollService.getEnrollByActiveId(info.getNo(), appActivityOrderReqVO.getUserId());
        if (Objects.isNull(activityEnrollDO)) {
            throw new UnsupportedOperationException("活动报名信息为空");
        }
        ActivityEnrollUpdateReqVO updateReqVO = new ActivityEnrollUpdateReqVO();
        updateReqVO.setId(activityEnrollDO.getId());
        updateReqVO.setPayAmount(info.getActiveCost());
        updateReqVO.setPayNo(String.valueOf(blindOrder));
        updateReqVO.setPayTime(LocalDateTime.now());

        String payway = appActivityOrderReqVO.getPayway();
        if (Objects.equals(payway, "1")) {
            updateReqVO.setPayType((byte) 1);
        } else {
            updateReqVO.setPayType((byte) 2);
        }

        activityEnrollService.updateEnroll(updateReqVO);

    }

    private Long createActivityOrder(AppActivityOrderReqVO appActivityOrderReqVO, ActivityInfoDO info, BlindMemberUserDO memberUser) {
        BlindTradeOrderCreateReqVO createReqVO = new BlindTradeOrderCreateReqVO();
        createReqVO.setOrderType((byte) 3);
        genNoCommonUtil.addOrderNo(createReqVO);
        createReqVO.setUserId(appActivityOrderReqVO.getUserId());
        createReqVO.setPayway(appActivityOrderReqVO.getPayway());
        createReqVO.setTerminal(appActivityOrderReqVO.getTerminal());
        createReqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
        createReqVO.setUserIp(getClientIP());
        createReqVO.setMobile(memberUser.getMobile());
        createReqVO.setUserName(memberUser.getNickname());
        createReqVO.setPayPrice(info.getActiveCost());
        createReqVO.setProductCount(1);
        createReqVO.setNotifyUrl("");
        createReqVO.setOpenContent("活动费用");
        createReqVO.setOpenNum("1");
        createReqVO.setTotalPrice(info.getActiveCost());
        return createBlindTradeOrder(createReqVO);
    }

    /**
     * 超级推荐
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRecommendMemberUser(RecommendSettingDO recommendSetting, BlindMemberUserDO memberUser) {
        BlindMemberUserUpdateReqVO updateReqVO = new BlindMemberUserUpdateReqVO();
        updateReqVO.setId(memberUser.getId());
        updateReqVO.setHaveRecommend((byte) 1);
//
        if (StringUtils.isNotBlank(memberUser.getRecommendNum())) {
            String recommendNum = memberUser.getRecommendNum();
            String num = recommendSetting.getNum();
            int totalNum = Integer.parseInt(recommendNum) + Integer.parseInt(num);
            updateReqVO.setRecommendNum(String.valueOf(totalNum));
        } else {
            updateReqVO.setRecommendNum(recommendSetting.getNum());
        }
        blindMemberUserService.updateMemberUser(updateReqVO);
    }

    private Long createRecommendOrder(AppRecommendOrderReqVO appRecommendOrderReqVO, RecommendSettingDO recommendSetting, BlindMemberUserDO memberUser) {

        BlindTradeOrderCreateReqVO createReqVO = new BlindTradeOrderCreateReqVO();
        createReqVO.setOrderType((byte) 2);
        genNoCommonUtil.addOrderNo(createReqVO);
        createReqVO.setOrderId(appRecommendOrderReqVO.getRecommendId());
        createReqVO.setUserId(appRecommendOrderReqVO.getUserId());
        createReqVO.setPayway(appRecommendOrderReqVO.getPayway());
        createReqVO.setTerminal(appRecommendOrderReqVO.getTerminal());
        createReqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
        createReqVO.setUserIp(getClientIP());
        createReqVO.setMobile(memberUser.getMobile());
        createReqVO.setUserName(memberUser.getNickname());
        createReqVO.setPayPrice(recommendSetting.getMoney());
        createReqVO.setProductCount(1);
        createReqVO.setNotifyUrl("");
        createReqVO.setOpenContent(recommendSetting.getNum() + "次");
        createReqVO.setOpenNum("1");
        createReqVO.setTotalPrice(recommendSetting.getMoney());
        createReqVO.setOpenLevel(PayOrderOpenLeveleEnum.SUPER_RECOMMENDATION.getName());
        Integer type = PayOrderOpenLeveleEnum.SUPER_RECOMMENDATION.getType();
        createReqVO.setOrderType(type.byteValue());
        return createBlindTradeOrder(createReqVO);
    }

    private Long createBlindMakerOrder(AppMakerOrderReqVO appdOrderReqVO, BlindMemberUserDO memberUser) {
        BlindTradeOrderCreateReqVO createReqVO = new BlindTradeOrderCreateReqVO();
        createReqVO.setOrderType((byte) 2);
        genNoCommonUtil.addOrderNo(createReqVO);
        createReqVO.setUserId(appdOrderReqVO.getUserId());
        createReqVO.setPayway(appdOrderReqVO.getPayway());
        createReqVO.setTerminal(appdOrderReqVO.getTerminal());
        createReqVO.setStatus(PayOrderStatusEnum.SUCCESS.getStatus());
        createReqVO.setUserIp(getClientIP());
        createReqVO.setMobile(memberUser.getMobile());
        createReqVO.setUserName(memberUser.getNickname());
        createReqVO.setPayPrice(appdOrderReqVO.getMoney());
        createReqVO.setProductCount(1);
        createReqVO.setNotifyUrl("");
        createReqVO.setOpenContent(appdOrderReqVO.getNum() + "次");
        createReqVO.setOpenNum(String.valueOf(appdOrderReqVO.getNum()));
        createReqVO.setTotalPrice(appdOrderReqVO.getMoney());
        createReqVO.setOpenLevel(PayOrderOpenLeveleEnum.MATCHMAKER_SERVICE.getName());
        // 红娘次数
        createReqVO.setOpenNum(String.valueOf(appdOrderReqVO.getNum()));
        // 红娘商品id
        createReqVO.setOrderId(appdOrderReqVO.getMakerProductId());
        Integer type = PayOrderOpenLeveleEnum.MATCHMAKER_SERVICE.getType();
        createReqVO.setOrderType(type.byteValue());
        // 红娘存入对应的红娘商品id
        createReqVO.setOrderId(appdOrderReqVO.getMakerProductId());
        return createBlindTradeOrder(createReqVO);
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateMemberUser(MemberMechanismDO memberMechanism, BlindMemberUserUpdateReqVO updateReqVO) {
        log.info("购买普通会员-更新会员信息开始：-{}", updateReqVO);
        genNoCommonUtil.addUserNo(updateReqVO);
        updateReqVO.setHaveMember((byte) 1);
        updateReqVO.setMemberBeginTime(LocalDateTime.now());
        String time = memberMechanism.getTime();
        if (Objects.equals(time, "1")) {
            LocalDateTime nowDateTimePlus30;
            if (Objects.nonNull(updateReqVO.getMemberEndTime())) {
                nowDateTimePlus30 = updateReqVO.getMemberEndTime().plusDays(30L);
            } else {
                nowDateTimePlus30 = LocalDateTime.now().plusDays(30L);
            }
            updateReqVO.setMemberEndTime(nowDateTimePlus30);
        } else {
            LocalDateTime nowDateTimePlus1;
            if (Objects.nonNull(updateReqVO.getMemberEndTime())) {
                nowDateTimePlus1 = updateReqVO.getMemberEndTime().plusYears(1L);
            } else {
                nowDateTimePlus1 = LocalDateTime.now().plusYears(1L);
            }
            updateReqVO.setMemberEndTime(nowDateTimePlus1);
        }

        if (Objects.equals(memberMechanism.getLevelId(), 1L)) {
            updateReqVO.setUserLevel((byte) 1);
        } else {
            updateReqVO.setUserLevel((byte) 2);
        }
        log.info("购买普通会员-更新会员信息结束：-{}", updateReqVO);
        blindMemberUserService.updateMemberUser(updateReqVO);
    }

    private Long createBlindOrder(AppBlindOrderCreateReqVO appBlindOrderCreateReqVO, MemberMechanismDO memberMechanism, BlindMemberUserDO memberUser) {
        BlindTradeOrderCreateReqVO createReqVO = new BlindTradeOrderCreateReqVO();
        genNoCommonUtil.addOrderNo(createReqVO);
        createReqVO.setOrderType((byte) 1);
        createReqVO.setUserId(appBlindOrderCreateReqVO.getUserId());
        createReqVO.setPayway(appBlindOrderCreateReqVO.getPayway());
        createReqVO.setTerminal(appBlindOrderCreateReqVO.getTerminal());
        // 所有的初创建订单都是未支付状态 暂时设置为支付成功
        createReqVO.setStatus(PayOrderStatusEnum.WAITING.getStatus());
        createReqVO.setUserIp(getClientIP());
        createReqVO.setMobile(memberUser.getMobile());
        createReqVO.setUserName(memberUser.getNickname());
        createReqVO.setPayPrice(memberMechanism.getMoney());
        if (Objects.nonNull(memberMechanism.getLevelId())) {
            if (Objects.equals(memberMechanism.getLevelId(), 1L)) {
                createReqVO.setOpenLevel(PayOrderOpenLeveleEnum.Regular_members.getName());
            } else {
                createReqVO.setOpenLevel(PayOrderOpenLeveleEnum.S_VIP.getName());
            }
        }
        // 用来存放会员机制
        createReqVO.setOrderId(memberMechanism.getId());
        createReqVO.setProductCount(1);
        createReqVO.setNotifyUrl("");
        createReqVO.setOpenContent(memberMechanism.getTime() + "个月");
        createReqVO.setOpenNum("1");
        createReqVO.setTotalPrice(memberMechanism.getMoney());
        return createBlindTradeOrder(createReqVO);
    }


    @Override
    public PayOrderSubmitRespVO createPayOrder(AppBlindOrderCreateRespVO vo) {
        PayOrderSubmitRespVO respVO = new PayOrderSubmitRespVO();
        if (Objects.nonNull(vo)) {
            //1.0 构建支付交易单
            PayOrderCreateReqDTO payOrder = new PayOrderCreateReqDTO();
            //1.1 获得相亲app的id
            PayAppDO payAppDO = payAppService.getApp(9L);
            if (Objects.nonNull(payAppDO)) {
                payOrder.setAppId(payAppDO.getId());
            } else {
                throw exception(PAY_ORDER_EXISTS);
            }
            payOrder.setBlindOrderId(vo.getMemberOrderId());
            if (vo.getType() == 1) {
                payOrder.setBlindOrderType(PayOrderTypeEnum.MEMBER_ACTIVATION.getType());
                payOrder.setBody("缘分计划-普通会员，用户开通普通会员");
                payOrder.setSubject("缘分计划-普通会员，用户开通的普通会员的支付缴费订单");
                payOrder.setMerchantOrderId(com.moxiao.yfjh.framework.common.util.number.NoCommonUtil.getUuid(vo.getMemberOrderId().toString()).toString());
            } else if (vo.getType() == 2) {
                //TODO 超级会员
                payOrder.setBlindOrderType(PayOrderTypeEnum.S_VIP.getType());
                payOrder.setBody("缘分计划-超级会员，用户开通超级会员");
                payOrder.setSubject("缘分计划-超级会员，用户开通超级会员的支付缴费订单");
                payOrder.setMerchantOrderId(com.moxiao.yfjh.framework.common.util.number.NoCommonUtil.getUuid(vo.getMemberOrderId().toString()).toString());
            } else if (vo.getType() == 3) {
                payOrder.setBlindOrderType(PayOrderTypeEnum.SUPER_RECOMMENDATION.getType());
                payOrder.setBody("缘分计划-超级推荐，会员购买超级推荐");
                payOrder.setSubject("缘分计划-超级推荐,会员用户购买超级推荐的缴费订单");
                payOrder.setMerchantOrderId(com.moxiao.yfjh.framework.common.util.number.NoCommonUtil.getUuid(vo.getMemberOrderId().toString()).toString());
            } else {
                payOrder.setBlindOrderType(PayOrderTypeEnum.MATCHMAKER_SERVICE.getType());
                payOrder.setBody("缘分计划-红娘服务，会员购买红娘服务");
                payOrder.setSubject("缘分计划-红娘服务,会员购买红娘服务缴费订单");
                payOrder.setMerchantOrderId(com.moxiao.yfjh.framework.common.util.number.NoCommonUtil.getUuid(vo.getMemberOrderId().toString()).toString());
            }
            //1.2 设置支付金额
            //TODO 设置支付金额为 1分钱
            payOrder.setPrice(1);
            //1.3 订单有效期
            LocalDateTime currentTime = LocalDateTime.now();
            LocalDateTime futureTime = currentTime.plusMinutes(30);
            payOrder.setExpireTime(futureTime);
            payOrder.setUserIp(getLoginUserId().toString());
            //2.0 创建支付交易单
            Long payOrderId = payOrderService.createOrder(payOrder);
            if (payOrderId != null) {
                //TODO 提交支付订单
                AppPayOrderSubmitReqVO reqVO = new AppPayOrderSubmitReqVO();
                reqVO.setId(payOrderId);
                BlindMemberUserDO userDO = blindMemberUserService.getMemberUser(vo.getMemberUserId());
                if (Objects.nonNull(userDO)) {
                    if (vo.getType() == 1) {
                        reqVO.setChannelCode("wx_app");
                    } else {
                        reqVO.setChannelCode("alipay_app");
                    }
                    try {
                        //TODO 设置支付金额为 1分钱
                        reqVO.setPrice(1);
                        respVO = payOrderService.submitOrder(reqVO, getClientIP());
                        log.info("支付成功返回：{}", reqVO);
                    } catch (Exception e) {
                        log.error("支付失败-{}", e.getMessage());
                    }
                } else {
                    throw exception(PAY_USER_NOT_ORDER_EXISTS);
                }
            }
        }
        return respVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyOrder(Long channelId, PayOrderRespDTO notify) {
        PayChannelDO payChannelDO = channelService.getChannel(channelId);
        // 一：支付成功的回调
        if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) {
            log.info("缘分计划-支付回调处理交易订单 -{}", notify);
            // 1. 查询 PayOrderExtensionDO
            PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo());
            if (Objects.nonNull(orderExtension)) {
                // 2. 通过 PayOrderExtensionDO 查询PayOrderDO 来 判断 PayOrderDO 是否存在
                PayOrderDO order = orderMapper.selectById(orderExtension.getOrderId());
                if (Objects.nonNull(order)) {

                    log.info("缘分计划-支付订单 -{}", order);
                    // 2.1.查询支付渠道
                    PayChannelDO channel = channelService.validPayChannel(channelId);
                    // 3. 查询相亲交易订单
                    BlindTradeOrderDO orderDO = getBlindTradeOrder(order.getBlindOrderId());
                    log.info("缘分计划-交易订单-支付回调 -{}", orderDO);
                    //3.1 更新相亲交易订单状态
                    blindTradeOrderMapper.update(null, new LambdaUpdateWrapper<BlindTradeOrderDO>()
                            .set(BlindTradeOrderDO::getPayStatus, 1)
                            .set(BlindTradeOrderDO::getPayOrderId, order.getId())
                            .set(BlindTradeOrderDO::getPayTime, new Date())
                            .set(BlindTradeOrderDO::getPayChannelCode, channel.getCode())
                            .eq(BlindTradeOrderDO::getId, orderDO.getId()));
                    // 4. 更想会员用户的会员状态
                    BlindMemberUserDO memberUserDO = blindMemberUserService.getMemberUser(orderDO.getUserId());
                    BlindMemberUserUpdateReqVO updateReqVO = new BlindMemberUserUpdateReqVO();
                    // 会员机制
                    MemberMechanismDO memberMechanism = new MemberMechanismDO();
                    // 超级推荐
                    RecommendSettingDO recommendSetting = new RecommendSettingDO();
                    switch (orderDO.getOpenLevel()) {
                        case "普通会员":
                            memberMechanism = memberMechanismService.getMemberMechanism(orderDO.getOrderId());
                            updateReqVO.setHaveMember((byte) 1);
                            updateReqVO.setId(memberUserDO.getId());
                            updateReqVO.setMemberEndTime(memberUserDO.getMemberEndTime());
                            getSelf().updateMemberUser(memberMechanism, updateReqVO);
                            log.info("缘分计划-会员更新-会员更新成功 -{}", orderDO);
                            break;
                        case "超级会员":
                            memberMechanism = memberMechanismService.getMemberMechanism(orderDO.getOrderId());
                            updateReqVO.setHaveMember((byte) 2);
                            updateReqVO.setId(memberUserDO.getId());
                            getSelf().updateMemberUser(memberMechanism, updateReqVO);
                            log.info("缘分计划-超级会员更新-更新成功 -{}", updateReqVO);
                            break;
                        case "超级推荐":
                            recommendSetting = recommendSettingService.getRecommendSetting(orderDO.getOrderId());
                            updateReqVO.setHaveRecommend((byte) 1);
                            updateReqVO.setId(memberUserDO.getId());
                            getSelf().updateRecommendMemberUser(recommendSetting, memberUserDO);
                            break;
                        default:
                            MatchmakerMemberStringingDO memberStringingDO = memberStringing.getSelectOne(orderDO.getUserId());
                            if (Objects.nonNull(memberStringingDO)) {
                                int num = memberStringingDO.getStringingNum() + Integer.parseInt(orderDO.getOpenNum());
                                memberStringing.updateNum(memberStringingDO.getId(), num);
                            } else {
                                MatchmakerMemberStringingCreateReqVO createReqVO = new MatchmakerMemberStringingCreateReqVO();
                                createReqVO.setStringingNum(Integer.valueOf(orderDO.getOpenNum()));
                                createReqVO.setMemberId(orderDO.getUserId());
                                createReqVO.setMemberName(memberUserDO.getNickname());
                                memberStringing.createMatchmakerMemberStringing(createReqVO);
                            }
                            break;
                    }
                }
            }
        }
        // 情况二：支付失败的回调
        if (PayOrderStatusRespEnum.isClosed(notify.getStatus())) {
            notifyOrderClosed(payChannelDO, notify);
        }
    }

    @Override
    public Integer getMakerSalesVolume(Long productId) {
        return blindTradeOrderMapper.getMakerSalesVolume(productId);
    }


    private void notifyOrderClosed(PayChannelDO channel, PayOrderRespDTO notify) {
        updateOrderExtensionClosed(channel, notify);
    }

    private void updateOrderExtensionClosed(PayChannelDO channel, PayOrderRespDTO notify) {
        // 1. 查询 PayOrderExtensionDO
        PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo());
        if (orderExtension == null) {
            throw exception(PAY_ORDER_EXTENSION_NOT_FOUND);
        }
        if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) { // 如果已经是关闭，直接返回，不用重复更新
            log.info("[updateOrderExtensionClosed][orderExtension({}) 已经是支付关闭，无需更新]", orderExtension.getId());
            return;
        }
        // 一般出现先是支付成功，然后支付关闭，都是全部退款导致关闭的场景。这个情况，我们不更新支付拓展单，只通过退款流程，更新支付单
        if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) {
            log.info("[updateOrderExtensionClosed][orderExtension({}) 是已支付，无需更新为支付关闭]", orderExtension.getId());
            return;
        }
        if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态，必须是待支付
            throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING);
        }

        // 2. 更新 PayOrderExtensionDO
        int updateCounts = orderExtensionMapper.updateByIdAndStatus(orderExtension.getId(), orderExtension.getStatus(),
                PayOrderExtensionDO.builder().status(PayOrderStatusEnum.CLOSED.getStatus()).channelNotifyData(toJsonString(notify))
                        .channelErrorCode(notify.getChannelErrorCode()).channelErrorMsg(notify.getChannelErrorMsg()).build());
        if (updateCounts == 0) { // 校验状态，必须是待支付
            throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING);
        }
        log.info("[updateOrderExtensionClosed][orderExtension({}) 更新为支付关闭]", orderExtension.getId());
    }

    public Object getObject(String sdkParam) throws UnsupportedEncodingException {
        // 解码URL参数字符串
        String decodedParamString = URLDecoder.decode(sdkParam, "UTF-8");
        // 将解码后的字符串转换为Map对象
        Map<String, String> paramMap = new HashMap<>();
        String[] params = decodedParamString.split("&");
        for (String param : params) {
            String[] keyValue = param.split("=");
            if (keyValue.length == 2) {
                paramMap.put(keyValue[0], keyValue[1]);
            }
        }
        // 输出Map对象
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
            System.out.println(entry.getKey() + " = " + entry.getValue());
        }
        return paramMap;
    }

    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private BlindTradeOrderServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }

}
